package org.jeecg.common.util.sms;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsResponse;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.util.StringUtils;
import org.jeecg.modules.system.entity.SmsEntity;
import org.jeecg.modules.system.entity.SysSmsConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


/**
 * 短信工具类
 * @author liurui
 * @date  2018年4月13日下午5:08:29
 * @version 1.0
 */
public class SmsUtil {
	/**log*/
    private static final Logger log = LoggerFactory.getLogger(SmsUtil.class);
    private static String accessKeyID = "LTAI4GFPVFAYHZe6Vk2e91bD";
    private static String accessKeySecret = "9ERGtnFm0WFpz2X85svtpAKxG8jcNf";
    private static String endpoint = "https://1603827182251019.mns.cn-shanghai.aliyuncs.com/";
    private static String topicName = "sms.topic-cn-shanghai";
    private static String signName = "镒安居"; //短信签名
    private static final String product = "Dysmsapi";//产品名称:云通信短信API产品,开发者无需替换
    private static final String domain = "dysmsapi.aliyuncs.com";//产品域名,开发者无需替换




    /**
     * 注册时采用的短信发送模板编码
     */
    public static final String REGISTER_TEMPLATE_CODE="SMS_144146309";

    /**
     * 通用短信发送方法
     * @param mobile 手机号
     * @param templateCode 模板编号
     * @param args 参数(key1,value1,key2,values...)
     * @return true:成功,false:失败
     */
    public synchronized static SmsEntity sendSms(String mobile, String templateCode,String ... args) {
       Map<String,String> params = new HashMap<>();
       for (int i = 0; i < args.length; i++) {
          if (i >= args.length - 1) {
             params.put(args[i], "");
             break;
          } else {
             params.put(args[i], args[i + 1]);
             i++;
          }
       }
       return sendSms(mobile, templateCode, params, null,null);
    }

    public synchronized static SmsEntity sendSmsWithConfig(SysSmsConfig config, String mobile, String ... args) {
        Map<String,String> params = new HashMap<>();
        for (int i = 0; i < args.length; i++) {
            if (i >= args.length - 1) {
                params.put(args[i], "");
                break;
            } else {
                params.put(args[i], args[i + 1]);
                i++;
            }
        }
        return sendSmsWithConfig(config, mobile, params, null,null);
    }

    /**
     * 通用短信发送方法
     * @param mobile 手机号
     * @param templateCode 模板编号
     * @param params 参数
     * @return true:成功,false:失败
     */
    public synchronized static SmsEntity sendSms(String mobile, String templateCode, Map<String,String> params, SmsEntity smsEntity, String _signName) {
       if (smsEntity == null){
           smsEntity = new SmsEntity();
           smsEntity.setStatus(false);
           smsEntity.setEsType(CommonConstant.SMS_TYPE_1);
       }
        //可自助调整超时时间
       System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
       System.setProperty("sun.net.client.defaultReadTimeout", "10000");
       try {
            //初始化acsClient,暂不支持region化
            IClientProfile profile = DefaultProfile.getProfile("cn-shanghai", accessKeyID, accessKeySecret);
            DefaultProfile.addEndpoint("cn-shanghai", "cn-shanghai", product, domain);
            IAcsClient acsClient = new DefaultAcsClient(profile);
            // 组装请求对象-具体描述见控制台-文档部分内容
            SendSmsRequest request = new SendSmsRequest();
          // 必填:待发送手机号
          request.setPhoneNumbers(mobile);
          // 必填:短信签名-可在短信控制台中找到
           request.setSignName(StringUtils.isEmpty(_signName) ? signName : _signName);
          // 必填:短信模板-可在短信控制台中找到
          request.setTemplateCode(templateCode);
          // 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
          if (params != null) {
             ObjectMapper objectMapper = new ObjectMapper();
             request.setTemplateParam(objectMapper.writeValueAsString(params));
          } else {
             request.setTemplateParam("{}");
          }
          //hint 此处可能会抛出异常，注意catch
          SendSmsResponse response = acsClient.getAcsResponse(request);
          if(response.getCode() != null && response.getCode().equals("OK")) {
              QuerySendDetailsResponse.SmsSendDetailDTO dto = querySendDetails(response.getBizId(),mobile,new Date());
              if (dto != null){
                  log.info("content: " + dto.getContent());
                  smsEntity.setContent(dto.getContent());
              }
              smsEntity.setBizId(response.getBizId());
              smsEntity.setTemplateCode(templateCode);
              smsEntity.setStatus(true);
              smsEntity.setMessage(response.getMessage());
              log.info("mobile: " + mobile);
              log.info("templateCode: " + templateCode);
              log.info("params: " + params);
              log.info("requestId: " + response.getRequestId());
              log.info("bizId: " + response.getBizId());
              log.info("message: " + response.getMessage());
              return smsEntity;
          } else {
              log.error("mobile: " + mobile);
              log.error("templateCode: " + templateCode);
              log.error("params: " + params);
              log.error("requestId: " + response.getRequestId());
              log.error("bizId: " + response.getBizId());
              log.error("message: " + response.getMessage());
              smsEntity.setBizId(response.getBizId());
              smsEntity.setTemplateCode(templateCode);
              smsEntity.setMessage(response.getMessage());
              return smsEntity;
          }
       } catch (Exception ex) {
          log.error("短信发送失败", ex);
       } finally {
          //client.close();
       }
       return smsEntity;
    }
    /**
     * 通用短信发送方法
     * @param mobile 手机号
     * @param params 参数
     * @return true:成功,false:失败
     */
    public synchronized static SmsEntity sendSmsWithConfig(SysSmsConfig config, String mobile, Map<String,String> params, SmsEntity smsEntity, String _signName) {
        if (smsEntity == null){
            smsEntity = new SmsEntity();
            smsEntity.setStatus(false);
            smsEntity.setEsType(CommonConstant.SMS_TYPE_1);
        }
        //可自助调整超时时间
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");
        try {
            //初始化acsClient,暂不支持region化
            IClientProfile profile = DefaultProfile.getProfile("cn-shanghai", config.getAccessKeyId(), config.getAccessKeySecret());
            DefaultProfile.addEndpoint("cn-shanghai", "cn-shanghai", config.getProduct(), config.getDomain());
            IAcsClient acsClient = new DefaultAcsClient(profile);
            // 组装请求对象-具体描述见控制台-文档部分内容
            SendSmsRequest request = new SendSmsRequest();
            // 必填:待发送手机号
            request.setPhoneNumbers(mobile);
            // 必填:短信签名-可在短信控制台中找到
            request.setSignName(config.getSignName());
            // 必填:短信模板-可在短信控制台中找到
            request.setTemplateCode(config.getTemplateCode());
            // 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
            if (params != null) {
                ObjectMapper objectMapper = new ObjectMapper();
                request.setTemplateParam(objectMapper.writeValueAsString(params));
            } else {
                request.setTemplateParam("{}");
            }
            //hint 此处可能会抛出异常，注意catch
            SendSmsResponse response = acsClient.getAcsResponse(request);
            if(response.getCode() != null && response.getCode().equals("OK")) {
                QuerySendDetailsResponse.SmsSendDetailDTO dto = querySendDetails(response.getBizId(),mobile,new Date());
                if (dto != null){
                    log.info("content: " + dto.getContent());
                    smsEntity.setContent(dto.getContent());
                }
                smsEntity.setBizId(response.getBizId());
                smsEntity.setTemplateCode(config.getTemplateCode());
                smsEntity.setStatus(true);
                smsEntity.setMessage(response.getMessage());
                log.info("mobile: " + mobile);
                log.info("templateCode: " + config.getTemplateCode());
                log.info("params: " + params);
                log.info("requestId: " + response.getRequestId());
                log.info("bizId: " + response.getBizId());
                log.info("message: " + response.getMessage());
                return smsEntity;
            } else {
                log.error("mobile: " + mobile);
                log.error("templateCode: " + config.getTemplateCode());
                log.error("params: " + params);
                log.error("requestId: " + response.getRequestId());
                log.error("bizId: " + response.getBizId());
                log.error("message: " + response.getMessage());
                smsEntity.setBizId(response.getBizId());
                smsEntity.setTemplateCode(config.getTemplateCode());
                smsEntity.setMessage(response.getMessage());
                return smsEntity;
            }
        } catch (Exception ex) {
            log.error("短信发送失败", ex);
        } finally {
        }
        return smsEntity;
    }

    public synchronized static QuerySendDetailsResponse.SmsSendDetailDTO querySendDetails(String bizId, String mobile, Date sendDate) {
        //可自助调整超时时间
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");
        try {
            Thread.sleep(500);
            //初始化acsClient,暂不支持region化
            IClientProfile profile = DefaultProfile.getProfile("cn-shanghai", accessKeyID, accessKeySecret);
            DefaultProfile.addEndpoint("cn-shanghai", "cn-shanghai", product, domain);
            IAcsClient acsClient = new DefaultAcsClient(profile);
            //组装请求对象
            QuerySendDetailsRequest request = new QuerySendDetailsRequest();
            //必填-号码
            request.setPhoneNumber(mobile);
            //可选-流水号
            request.setBizId(bizId);
            //必填-发送日期 支持30天内记录查询，格式yyyyMMdd
            SimpleDateFormat ft = new SimpleDateFormat("yyyyMMdd");
            if (sendDate == null){
                request.setSendDate(ft.format(new Date()));
            } else {
                request.setSendDate(ft.format(sendDate));
            }
            //必填-页大小
            request.setPageSize(10L);
            //必填-当前页码从1开始计数
            request.setCurrentPage(1L);
            //hint 此处可能会抛出异常，注意catch
            QuerySendDetailsResponse querySendDetailsResponse = acsClient.getAcsResponse(request);
            if (querySendDetailsResponse.getSmsSendDetailDTOs().size() > 0){
                return querySendDetailsResponse.getSmsSendDetailDTOs().get(0);
            } else{
                return null;
            }
        } catch (Exception ex) {
            log.error("短信详细查询异常",ex);
            return null;
        }
    }


    public static void main(String[] args) {
       SmsEntity smsEntity =  sendSms("15618750343","SMS_153725766",null,"carName","皖A");
       System.out.println(smsEntity);
    }
}
